package com.kgis.map.layer
{
	import com.kgis.map.Map;
	import com.kgis.map.common.enum.LayerTypeEnum;
	import com.kgis.map.common.util.Util;
	import com.kgis.map.events.EditEvent;
	import com.kgis.map.events.FeatureEvent;
	import com.kgis.map.events.MapEvent;
	import com.kgis.map.feature.Feature;
	import com.kgis.map.geometry.PointGeometry;
	import com.kgis.map.geometry.basetype.Extent;
	import com.kgis.map.handler.feature.draw.snap.SnapReturn;
	import com.kgis.map.handler.feature.draw.snap.SnapTypeEnum;
	import com.kgis.map.rule.IRule;
	import com.kgis.map.style.IStyle;
	import com.kgis.map.style.LabelStyle;
	import com.kgis.map.task.query.LayerExtentQuery;
	import com.kgis.map.task.query.LayerLogicalMapIdQuery;
	import com.kgis.widgets.managers.ErrorManager;
	
	import flash.display.DisplayObject;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.utils.getTimer;
	
	import mx.collections.ArrayCollection;

	/**
	 * 矢量设施图层
	 */
	public class FeatureLayer extends Layer
	{
		/**标注内容*/
		private var _labelContent:String=null;
		/**几何体样式*/
		private var _geoStyle:IStyle=null;
		/**标注样式*/
		private var _labelStyle:IStyle=null;
		/**选中样式*/
		private var _geoSelectStyle:IStyle=null;
		private var _labelSelectedStyle:IStyle=null;
		/**高亮样式*/
		private var _geoHighLightStyle:IStyle=null;
		private var _labelHighLightStyle:IStyle=null;
		/**样式规则*/
		private var _geoStyleRule:IRule=null;
		private var _labelStyleRule:IRule=null;
		/**标注规则*/
		private var _labelContentRule:IRule=null;
		private var _dataFilter:String=null;
		/**图层几何体类型*/
		private var _geometryType:int;
		/**图层符号最大显示等级*/
		private var _maxZoomLevel:int=18;
		/**图层符号最小显示等级*/
		private var _minZoomLevel:int=0;
		private var _maxZoomLevelLabel:int=18;
		private var _minZoomLevelLabel:int=0;
		/**图层是否在显示等级范围内显示*/
		private var _levelable:Boolean=true;
		private var _labelLevelable:Boolean=true;
		/**图层上的设施是否可以选择*/
		private var _selectable:Boolean=true;
		/**选中的设施列表*/
		private var _selectedFeatures:Vector.<Feature>=new Vector.<Feature>();
		
		/**图层上objectid列表*/
		private var _featuresIDs:Vector.<Number>=new Vector.<Number>();
		private var _layerType:int=LayerTypeEnum.MAPLAYER; //图层类型   数据库矢量层、动态图层
		/**是否显示标注*/
		private var _labelVisible:Boolean=true;
		/**是否有自动标注*/
		private var _hasAutoLabel:Boolean=false;

		/*是否全部刷新图层*/
		private var _fullRedraw:Boolean=false;
			
		private var _glow:GlowFilter=null; //new GlowFilter(0X0000FF,1,10,10);//晕圈

		public function FeatureLayer(id:int, name:String)
		{
			super(id, name);
			// 平滑移动
			this.cacheAsBitmap=true;
			// 缩放效果
			this.tweenOnZoom=false;

		}

		/**是否按level显示*/
		public function get levelable():Boolean
		{
			return _levelable;
		}

		/**
		 * @private
		 */
		public function set levelable(value:Boolean):void
		{
			_levelable=value;
		}

		/**最小显示level*/
		public function get minZoomLevel():int
		{
			return _minZoomLevel;
		}

		/**
		 * @private
		 */
		public function set minZoomLevel(value:int):void
		{
			_minZoomLevel=value;
		}

		/**最大显示level*/
		public function get maxZoomLevel():int
		{
			return _maxZoomLevel;
		}

		/**
		 * @private
		 */
		public function set maxZoomLevel(value:int):void
		{
			_maxZoomLevel=value;
		}

		override public function destroy():void
		{
			super.destroy();
			this.removeFeatures(this.features);
			this.selectedFeatures=null;
			this._featuresIDs=null;
			this._glow=null;
			this._geoStyle=null;
			this._labelStyle=null;
			this._geoSelectStyle=null;
			this._labelSelectedStyle=null;
			this._geoHighLightStyle=null;
			this._labelHighLightStyle=null;
			this._geoStyleRule=null;
			this._labelStyleRule=null;
			this._labelContentRule=null;
		}

		// Clear layer and children graphics
		override public function clear():void
		{
			var child:Feature=null;
			var numChild:int=this.numChildren;
			var i:int;
			var j:int;
			var numChild2:int;
			for (i=0; i < numChild; ++i)
			{
				child=this.getChildAt(i) as Feature;
				child.clear();
			}
			this.graphics.clear();
		}

		override public function set map(map:Map):void
		{
			super.map=map;
		}

		/**
		 * Add Features to the layer.
		 *
		 * @param features array
		 */
		public function addFeatures(features:Vector.<Feature>):void
		{
			var fevt:FeatureEvent=null;

			/*			// Dispatch an event before the features are added
			   if (this.map)
			   {
			   fevt=new FeatureEvent(FeatureEvent.FEATURE_PRE_INSERT, null);
			   fevt.features=features;
			   this.map.dispatchEvent(fevt);
			 }*/

			var i:int;
			var j:int=features.length
			for (i=0; i < j; i++)
			{
				this.addFeature(features[i], false, false);
			}

			// Dispatch an event with all the features added
		/*			if (this.map)
		   {
		   fevt=new FeatureEvent(FeatureEvent.FEATURE_INSERT, null);
		   fevt.features=features;
		   this.map.dispatchEvent(fevt);
		 }*/
		}

		/**
		 * Add Feature to the layer.
		 *
		 * @param feature The feature to add
		 */
		public function addFeature(feature:Feature, dispatchFeatureEvent:Boolean=true, reproject:Boolean=true):void
		{
			if (feature == null)
			{
				return;
			}
			if (this._featuresIDs.indexOf(feature.objectId) != -1)
				return;

			this._featuresIDs.push(feature.objectId);

			var fevt:FeatureEvent=null;
			// Check if the feature may be added to this layer
			var vectorfeature:Feature=feature;
			/*if (this.geometryType && (getQualifiedClassName(vectorfeature.geometry) != this.geometryType)) {
				var throwStr:String = "addFeatures : component should be an " + getQualifiedClassName(this.geometryType);
				throw throwStr;
			}*/

			// If needed dispatch a PRE_INSERT event before the feature is added
			/*			if (dispatchFeatureEvent && this.map)
			   {
			   fevt=new FeatureEvent(FeatureEvent.FEATURE_PRE_INSERT, feature);
			   this.map.dispatchEvent(fevt);
			 }*/

			/*			// Reprojection if needed
			   if (reproject && (this.map) && (this.projection.srsCode != this._displayProjection.srsCode)) {
			   feature.geometry.transform(this.projection, this._displayProjection);
			 }*/

			// Add the feature to the layer
			feature.layer=this;
			this.addChild(feature);

			//Simon He 修改
		/*if (this.map)
			feature.executeDrawing();*/

		/*			// If needed, dispatch an event with the feature added
		   if (dispatchFeatureEvent && this.map)
		   {
		   fevt=new FeatureEvent(FeatureEvent.FEATURE_INSERT, feature);
		   this.map.dispatchEvent(fevt);
		 }*/
		}

		override public function reset():void
		{
			//移除图层上的设施 ，选中的和处于编辑状态的不删除
			var feas:Vector.<Feature>=new Vector.<Feature>();
			var deleted:Boolean=false;
			for each (var fea:Feature in features)
			{
				if (!fea.selected && !fea.editing)
				{
					feas.push(fea);
					deleted=true;
				}
			}
			this.removeFeatures(feas);

		}

		override public function redraw(fullRedraw:Boolean=false):void
		{

			if (!displayed)
			{
				this.clear();
				this.loading=false;
				return;
			}

			//加载矢量数据
			this.loading=true;
			
			//是否全部刷新图层
			this._fullRedraw=fullRedraw;

			//对于数据库图层，需要重新加载数据
			if (this.layerType == LayerTypeEnum.MAPLAYER)
			{
				var eQuery:LayerExtentQuery=new LayerExtentQuery(this.id, this.map.extent);
				eQuery.onResult=onQueryByExtent;
				eQuery.onFault=onQueryByExtentFault;
				eQuery.execute();
			}
			else if (this.layerType == LayerTypeEnum.LOGICALMAPLAYER)
			{
				var eLogicalQuery:LayerLogicalMapIdQuery=new LayerLogicalMapIdQuery(this.id, this.map.logicalMapId);
				eLogicalQuery.onResult=onQueryByLogicalMapId;
				eLogicalQuery.onFault=onQueryByLogicalMapIdFault;
				eLogicalQuery.execute();
			}
			else if(this.layerType==LayerTypeEnum.DYNAMICLAYER)
			{
				this.draw();
			}
		}

		override protected function draw():void
		{
			var j:int=this.numChildren - 1;
			var o:DisplayObject;
			for (j; j > -1; j--)
			{
				o=this.getChildAt(j);
				if (o is Feature)
					(o as Feature).executeDrawing();
			}
			this.loading=false;
		}

		public function removeFeatures(features:Vector.<Feature>):void
		{
			if (!features)
			{
				return;
			}
			var i:int=features.length - 1;
			for (i; i > -1; i--)
				this.removeFeature(features[i], false);
			// Dispatch an event with all the features removed
			if (this.map)
			{
				var fevt:EditEvent=new EditEvent(EditEvent.FEATURE_DELETED, null, null, Util.vectorToArrayCollection(features));
				this.map.dispatchEvent(fevt);
			}
		}

		public function removeFeature(feature:Feature, dispatchFeatureEvent:Boolean=true):void
		{
			if (feature == null)
				return;

			var i:int=this._featuresIDs.indexOf(feature.objectId);
			if (i == -1)
				return;
			this._featuresIDs.splice(i, 1);

			var j:int=this.numChildren - 1;
			for (j; j > -1; j--)
			{
				if (this.getChildAt(j) == feature)
				{
					this.removeChildAt(j);
					break;
				}
			}
			//从选择集里移除
			i=this.selectedFeatures.indexOf(feature);
			if (i != -1)
			{
				this.selectedFeatures.splice(i, 1);
			}
			
			
			
			// If needed, dispatch an event with the feature added
			if (dispatchFeatureEvent && this.map)
			{
				var fevt:EditEvent=new EditEvent(EditEvent.FEATURE_DELETED, feature);
				this.map.dispatchEvent(fevt);
			}

			feature.destroy();
		}

		//Getters and setters
		public function get features():Vector.<Feature>
		{
			var _features:Vector.<Feature>=new Vector.<Feature>();
			var j:int=this.numChildren - 1;
			var o:DisplayObject;
			for (j; j > -1; --j)
			{
				o=this.getChildAt(j)
				if (o is Feature)
				{
					_features.push(o);
				}
			}
			return _features;
		}

		/**
		 * 根据object id获取设施
		 * @param 设施id.
		 * @return id对应的feature,如果找不到相应的feature，则返回Null.
		 *
		 */
		public function getFeatureById(id:Number):Feature
		{
			var foundFeature:Feature=null;
			var count:Number=this.features.length;
			for (var i:Number=0; i < count; i++)
			{
				var fea:Feature=this.features[i];
				if (fea.objectId == id)
				{
					foundFeature=fea;
				}
			}
			return foundFeature;
		}


		public function get featuresIDs():Vector.<Number>
		{
			return _featuresIDs;
		}

		override public function get geoInRange():Boolean
		{
			// 是否在显示level范围内
			if (!this.levelable)
			{
				return true;
			}
			else
			{
				return map.zoom <= this.maxZoomLevel && map.zoom >= this.minZoomLevel;
			}
		}

		override public function get labelInRange():Boolean
		{
			// 是否在显示level范围内
			if (!this.labelLevelable)
			{
				return true;
			}
			else
			{
				return map.zoom <= this.maxZoomLevelLabel && map.zoom >= this.minZoomLevelLabel;
			}
		}

		override protected function onMapMove(e:MapEvent):void
		{
			//没有移动
			if (e.newCenter == e.oldCenter && e.newZoom == e.oldZoom)
			{
				return;
			}
			this.redraw();
		}

		public function get selectedFeatures():Vector.<Feature>
		{
			return this._selectedFeatures;
		}

		public function set selectedFeatures(value:Vector.<Feature>):void
		{
			this._selectedFeatures=value;
		}

		
		
		public function get geometryType():int
		{
			return this._geometryType;
		}

		public function set geometryType(value:int):void
		{
			this._geometryType=value;
		}

		public function get layerType():int
		{
			return _layerType;
		}

		public function set layerType(value:int):void
		{
			_layerType=value;
		}

		public function get labelContent():String
		{
			return _labelContent;
		}

		public function set labelContent(value:String):void
		{
			_labelContent=value;
		}

		/**标准显示样式*/
		public function get geoStyle():IStyle
		{
			return _geoStyle;
		}

		/**
		 * @private
		 */
		public function set geoStyle(value:IStyle):void
		{
			_geoStyle=value;
		}

		public function get labelStyle():IStyle
		{
			if (_labelStyle == null)
			{
				_labelStyle=LabelStyle.getDefaultStyle();
			}
			return _labelStyle;
		}

		public function set labelStyle(value:IStyle):void
		{
			_labelStyle=value;
		}

		/**选中显示样式*/
		public function get geoSelectStyle():IStyle
		{
			return _geoSelectStyle;
		}

		/**
		 * @private
		 */
		public function set geoSelectStyle(value:IStyle):void
		{
			_geoSelectStyle=value;
		}

		public function get labelSelectedStyle():IStyle
		{
			return _labelSelectedStyle;
		}

		public function set labelSelectedStyle(value:IStyle):void
		{
			_labelSelectedStyle=value;
		}

		/**高亮显示样式*/
		public function get geoHighLightStyle():IStyle
		{
			return _geoHighLightStyle;
		}

		public function set geoHighLightStyle(value:IStyle):void
		{
			_geoHighLightStyle=value;
		}
		
		public function get labelHighLightStyle():IStyle
		{
			return _labelHighLightStyle;
		}
		
		public function set labelHighLightStyle(value:IStyle):void
		{
			_labelHighLightStyle=value;
		}
		
		
		public function get geoStyleRule():IRule
		{
			return _geoStyleRule;
		}

		public function set geoStyleRule(value:IRule):void
		{
			_geoStyleRule=value;
		}

		public function get labelStyleRule():IRule
		{
			return _labelStyleRule;
		}

		public function set labelStyleRule(value:IRule):void
		{
			_labelStyleRule=value;
		}

		public function get labelContentRule():IRule
		{
			return _labelContentRule;
		}

		public function set labelContentRule(value:IRule):void
		{
			_labelContentRule=value;
		}

		public function snapFeature(mousePoint:PointGeometry, snapTolerance:Number):SnapReturn
		{
			//获取分辨率，查找此像素单位的实地距离
			var distance:Number=map.resolution * snapTolerance;
			var snapPoint:PointGeometry=new PointGeometry;
			var snapReturn:SnapReturn=new SnapReturn();
//			snapReturn.snapLayer=this;
			
			var features:ArrayCollection;
//			getObjectsUnderPoint(new Point(mousePoint.x,mousePoint.y));
			for each (var feature:Feature in this.features)
			{
				snapReturn.snapType=feature.geometry.getTolerancePoint(mousePoint, distance, snapPoint);
				if (snapReturn.snapType != SnapTypeEnum.NO_SNAPS)
				{
					snapReturn.snapPoint=snapPoint;
					snapReturn.snapFeature=feature;
					snapReturn.snapFeatures.addItem(feature);
//					if(snapReturn.snapMap.containsKey(snapPoint)){
//						snapReturn.snapMap.getObject(snapPoint).addItem(feature);
//					}else{
//						features=new ArrayCollection();
//						features.addItem(feature);
//						snapReturn.snapMap.put(snapPoint,features);
//					}
//					break;
				}

			}
//			snapReturn.snapMap.put(snapPoint,snapFeatures);
			return snapReturn;
		}
		/**图层上的设施是否可选*/
		public function get selectable():Boolean
		{
			return _selectable;
		}

		/**
		 * @private
		 */
		public function set selectable(value:Boolean):void
		{
			//根据是否可选图层上设施的事件监听状态
			var fea:Feature;
			if (value != this._selectable) //选择状态有改变才调用
			{
				if (value)
				{
					for each (fea in features)
					{
						fea.registerListeners();
					}
				}
				else
				{
					for each (fea in features)
					{
						fea.unregisterListeners();
					}
				}
			}
			_selectable=value;
		}

		/**图层标注最大显示等级*/
		public function get maxZoomLevelLabel():int
		{
			return _maxZoomLevelLabel;
		}

		/**
		 * @private
		 */
		public function set maxZoomLevelLabel(value:int):void
		{
			_maxZoomLevelLabel=value;
		}

		/**图层标注最小显示等级*/
		public function get minZoomLevelLabel():int
		{
			return _minZoomLevelLabel;
		}

		/**
		 * @private
		 */
		public function set minZoomLevelLabel(value:int):void
		{
			_minZoomLevelLabel=value;
		}

		/**根据图层id和地图范围获取 矢量设施数据*/
		private function onQueryByExtent(layerData:LayerData, token:Object=null):void
		{
			if (!layerData || !layerData.features)
			{
				this.loading=false;
				return;
			}

			var layer:FeatureLayer=this.map.getLayerById(layerData.layerId) as FeatureLayer;
			if (!layer)
			{
				trace("没有取到layerData对应的图层");
				this.loading=false;
				return;
			}
			var _curtime:int=getTimer();
			//重新加载图层矢量数据
			layer.refeshByLayerData(layerData);
			trace("layerid:" + this.name + "," + this.id.toString() + ",数量:" + this.featuresIDs.length.toString() + ",刷新耗时:" + (getTimer() - _curtime).toString());
		}

		private function onQueryByExtentFault(info:String, token:Object=null):void
		{
			this.loading=false;
			ErrorManager.showErrorMessage("根据extent查询图层数据错误!" + info);
		}

		/**根据图层id和logicalmapid 获取 矢量设施数据*/
		private function onQueryByLogicalMapId(layerData:LayerData, token:Object=null):void
		{
			if (!layerData || !layerData.features)
			{
				this.loading=false;
				return;
			}

			var layer:FeatureLayer=this.map.getLayerById(layerData.layerId) as FeatureLayer;
			if (!layer)
			{
				trace("没有取到layerData对应的逻辑图图层");
				this.loading=false;
				return;
			}
			var _curtime:int=getTimer();
			//重新加载图层矢量数据
			layer.refeshByLayerData(layerData);
			trace("layerid:" + this.name + "," + this.id.toString() + ",数量:" + this.featuresIDs.length.toString() + ",刷新耗时:" + (getTimer() - _curtime).toString());
		}

		private function onQueryByLogicalMapIdFault(info:String, token:Object=null):void
		{
			this.loading=false;
			ErrorManager.showErrorMessage("查询逻辑图图层数据错误!" + info);
		}

		/**
		 * 根据layerdata刷新图层
		 */
		public function refeshByLayerData(layerdata:LayerData):void
		{
			var lasttime:int=0;
			var escapetime:int=0;

			try
			{
				if (this.layerType == LayerTypeEnum.MAPLAYER)
				{
					if (!layerdata.extent.equals(this.map.extent))
					{
						this.loading=false;
						return;
					}
				}

				lasttime=getTimer();

				//需要增加的设施
				var addFeatures:Vector.<Feature>=new Vector.<Feature>();
				//需要从图层上删除的设施
				var delFeatures:Vector.<Feature>=new Vector.<Feature>();
				//现有图层上的设施
				var currentFeatures:Vector.<Feature>=this.features;
				//server端返回来的layerdata arraycollection
				var layerdataFeatures:ArrayCollection=layerdata.features;
				//layerdata objectid vector方式
				var totalLayerdataFeatureIds:Vector.<Number>=new Vector.<Number>();

				var nCount:int=layerdata.features.length;
				var i:int=0,j:int=0;
				
				
				//现有图层已有feature，仅仅更新geometry；现有图层没有的需要新增feature
				for (i=0; i < nCount; i++)
				{
					var fea:Feature=layerdataFeatures.getItemAt(i) as Feature;
					totalLayerdataFeatureIds.push(fea.objectId);
					if (this._featuresIDs.indexOf(fea.objectId) < 0)
					{
						//加入需要新增的设施列表(在窗口范围内)
						if (onScreen(fea))
							addFeatures.push(layerdataFeatures.getItemAt(i));
					}
					
				}
				

				//删除掉现有图层上不在layerdata的
				var curcount:int=currentFeatures.length;
				for (i=0; i < curcount; i++)
				{
					var ff:Feature=currentFeatures[i];
					j=totalLayerdataFeatureIds.indexOf(ff.objectId);
					if ((j < 0 && ff.editing == false && ff.isLocked == false) || (j >= 0 && !onScreen(ff)))
					{
						delFeatures.push(ff);
					}
				}
				this.removeFeatures(delFeatures);
				
				if(this._fullRedraw)
				{
					currentFeatures=this.features;
					for(i=0;i<nCount;i++)
					{
						fea=layerdataFeatures.getItemAt(i) as Feature;
						for each (var f:Feature in currentFeatures) {
							if (f.objectId == fea.objectId && f.editing == false && f.isLocked == false) {
								f.geometry = fea.geometry;
								f.fieldsMap = fea.fieldsMap;
								break;
							}
						}
						
					}
					this._fullRedraw=false;
				}
				
				//新增设施到本图层
				this.addFeatures(addFeatures);
				
				escapetime=0;
				lasttime=getTimer();
				this.draw();
				escapetime=getTimer() - lasttime;
				trace(this.id.toString() + "redraw_features,耗时：" + escapetime.toString());
			}
			catch (e:Error)
			{
				ErrorManager.showErrorMessage("刷新图层数据出错,layerid:" + this.id.toString() + " " + e.message);
				this.loading=false;
			}
		}

		/**数据过滤条件*/
		public function get dataFilter():String
		{
			return _dataFilter;
		}

		/**
		 * @private
		 */
		public function set dataFilter(value:String):void
		{
			_dataFilter=value;
		}

		public function get glow():GlowFilter
		{
			if (_glow == null)
			{
				_glow=new GlowFilter(0x00ff00, 1, 3, 3);
			}
			return _glow;
		}

		public function set glow(value:GlowFilter):void
		{
			_glow=value;
		}

		/**是否显示标注*/
		public function get labelVisible():Boolean
		{
			return _labelVisible;
		}

		/**
		 * @private
		 */
		public function set labelVisible(value:Boolean):void
		{
			_labelVisible=value;
		}

		override public function clone():Layer
		{
			var featurelayer:FeatureLayer=new FeatureLayer(this.id, this.name);
			featurelayer.labelContent=this.labelContent;
			featurelayer.geoStyle=(this.geoStyle == null) ? null : this.geoStyle.clone();
			featurelayer.labelStyle=(this.labelStyle == null) ? null : this.labelStyle.clone();
			featurelayer.geoSelectStyle=(this.geoSelectStyle == null) ? null : this.geoSelectStyle.clone();
			featurelayer.labelSelectedStyle=(this.labelSelectedStyle == null) ? null : this.labelSelectedStyle.clone();
			featurelayer.geoHighLightStyle=(this.geoHighLightStyle == null) ? null : this.geoHighLightStyle.clone();
			featurelayer.labelHighLightStyle=(this.labelHighLightStyle == null) ? null : this.labelHighLightStyle.clone();
			featurelayer.geoStyleRule=(this.geoStyleRule == null) ? null : this.geoStyleRule.clone();
			featurelayer.labelStyleRule=(this.labelStyleRule == null) ? null : this.labelStyleRule.clone();
			featurelayer.labelContentRule=(this.labelContentRule == null) ? null : this.labelContentRule.clone();
			featurelayer.dataFilter=this.dataFilter;
			featurelayer.geometryType=this.geometryType;
			featurelayer.maxZoomLevel=this.maxZoomLevel;
			featurelayer.minZoomLevel=this.minZoomLevel;
			featurelayer.maxZoomLevelLabel=this.maxZoomLevelLabel;
			featurelayer.minZoomLevelLabel=this.minZoomLevelLabel;
			featurelayer.levelable=this.levelable;
			featurelayer.selectable=this.selectable;
			featurelayer.layerType=this.layerType
			featurelayer.labelVisible=this.labelVisible;
			featurelayer.glow=this.glow;
			featurelayer.hasAutoLabel=this.hasAutoLabel;


			return featurelayer;
		}

		/**
		 *根据分析原点做一个extent，与featureLayer上的feature做分析，默认以4个像素为单位
		 *@param point
		 *       Analysis of the origin point
		 *@param tolerance
		 *       Buffer analysis tolerance In pixels,
		 * */
		public function pointBufferAnalysis(point:PointGeometry, tolerance:int=4):ArrayCollection
		{
			//获取分辨率，查找此像素单位的实地距离
			var distance:Number=map.resolution * tolerance;
			var originExtent:Extent=new Extent(point.x - distance, point.y - distance, point.x + distance, point.y + distance);
			var result:ArrayCollection=new ArrayCollection();
			var snapPoint:PointGeometry=new PointGeometry();
			for (var i:int=0; i < this.features.length; i++)
			{
				var feature:Feature=this.features[i];
				if (feature.geometry.getExtent().intersectsBounds(originExtent, true))
				{
					//计算点与feature各个节点的距离
					if (SnapTypeEnum.SNAP_OVERTEX == feature.geometry.getTolerancePoint(point, distance, snapPoint))
					{
						result.addItem(feature);
					}
				}
			}
			return result;
		}

		public function get labelLevelable():Boolean
		{
			return _labelLevelable;
		}

		public function set labelLevelable(value:Boolean):void
		{
			_labelLevelable=value;
		}

		public function get hasAutoLabel():Boolean
		{
			return _hasAutoLabel;
		}

		public function set hasAutoLabel(value:Boolean):void
		{
			_hasAutoLabel=value;
		}

		/**
		 * Determines if the feature is visible on the screen
		 */
		public function onScreen(fea:Feature):Boolean
		{
			var onScreen:Boolean=false;

			if (!fea.geometry)
			{
				return false;
			}

			var currentmapextent:Extent=this.map.extent;
			var featureextent:Extent=fea.geometry.getExtent();
			if (currentmapextent.intersectsBounds(featureextent))
			{
				onScreen=true;
			}
			else
			{
				//trace("图层:" + this.layer.layerId.toString() + ",设施:" + this.objectId.toString() + "不在当前地图范围内,设施Extent:"+featureextent.toString()+";地图窗口Extent:"+currentmapextent.toString());
				onScreen=false;
			}

			return onScreen;

		}
	}
}
